package Waya::Board::AsImage;

use warnings;
use strict;
use Waya::Constants ':colors';
use GD;

use base 'Waya::Base';

sub init {
    my $self = shift;
    $self->SUPER::init(@_);
    $self->{imagesize}    = 285   unless $self->{imagesize};
    $self->{boardsize}    = 19    unless $self->{boardsize};
    $self->{antialias}    = 0     unless defined $self->{antialias};

    $self->{stonesize}    = int( $self->{imagesize} / $self->{boardsize} );
    $self->{border}       = int( ($self->{imagesize} - ($self->{stonesize} * $self->{boardsize})) /2 ) + int($self->{stonesize}/2);
    $self->{image}        = GD::Image->newTrueColor($self->{imagesize},$self->{imagesize});

    if ($self->{gobanColor}) {
        $self->{gobanColor}   = $self->{image}->colorAllocate(@{ $self->{gobanColor} });
    } else {
        $self->{gobanColor}   = $self->{image}->colorAllocate(0xee,0xb1,0x4b);
    }
    if ($self->{whiteColor}) {
        $self->{whiteColor}   = $self->{image}->colorAllocate(@{ $self->{whiteColor} });
    } else {
        $self->{whiteColor}   = $self->{image}->colorAllocate(0xff,0xff,0xff);
    }
    if ($self->{blackColor}) {
        $self->{blackColor}   = $self->{image}->colorAllocate(@{ $self->{blackColor} });
    } else {
        $self->{blackColor}   = $self->{image}->colorAllocate(0x00,0x00,0x00);
    }
}


sub drawGoban {
    my $self = shift;
    my $color = $self->{image}->colorAllocate(0,0,0);
    my $bottomright = $self->{stonesize} * $self->{boardsize} - ($self->{stonesize} - $self->{border});

    $self->{image}->fill(0,0,$self->{gobanColor});
    $self->{image}->setThickness(1);

    $self->{image}->rectangle($self->{border},$self->{border},$bottomright,$bottomright,$color);
    foreach my $x (($self->{border} + $self->{stonesize})..$bottomright) {
        next if (($x-$self->{border}) % $self->{stonesize});
        $self->{image}->line($x,$self->{border},$x,$bottomright,$color);
        $self->{image}->line($self->{border},$x,$bottomright,$x,$color);
    }
    if ($self->{antialias}) {
        $self->{image}->setAntiAliased($color);
        $color = gdAntiAliased;
    }
    my %hoshi = (   5   => [[2,2]                   ], 
                    7   => [[3,3]                   ], 
                    9   => [[2,2],          [6,2],
                                    [4,4],  
                            [2,6],          [6,6]   ], 
                    11  => [[3,3],          [7,3],
                                    [5,5],
                            [3,7],          [7,7]   ],
                    13  => [[2,2],  [6,2],  [10,2],
                            [2,6],  [6,6],  [10,6],
                            [2,10], [6,10], [10,10]   ],
                    19  => [[3,3],  [9,3],  [15,3],
                            [3,9],  [9,9],  [15,9],
                            [3,15], [9,15], [15,15] ],
                );
    foreach my $point (@{ $hoshi{$self->{boardsize}} }) {
        my $x = $self->{border}+($self->{stonesize}*$point->[0]);
        my $y = $self->{border}+($self->{stonesize}*$point->[1]);
        $self->{image}->filledEllipse($x,$y,$self->{stonesize}/4,$self->{stonesize}/4,$color)
    }
}


sub placeStone {
    my ($self, $coord, $stone_color) = @_;
    
    my $x = $self->{border}+($self->{stonesize}*($coord->x - 1));
    my $y = $self->{border}+($self->{stonesize}*($coord->y - 1));

    my $color = $self->{$stone_color . "Color"};
    if ($self->{antialias}) {
        $self->{image}->setAntiAliased($color);
        $color = gdAntiAliased
    }
    $self->{image}->filledEllipse($x,$y,$self->{stonesize},$self->{stonesize},$color);

    if (($stone_color eq WHITE) && ($self->{stonesize} > 9)) {
        $color=$self->{blackColor};
        if ($self->{antialias}) {
            $self->{image}->setAntiAliased($color);
            $color = gdAntiAliased
        }
        $self->{image}->ellipse($x,$y,$self->{stonesize},$self->{stonesize},$color);
    }
}


sub render_image {
    my ($self, $board, $bounds) = @_;
    my ($left, $right, $top, $bottom);
    if (ref $bounds eq 'Waya::Bounds') {
        ($left, $right, $top, $bottom) =
            ($bounds->left, $bounds->right, $bounds->top, $bounds->bottom);
    } else {
        ($left, $right, $top, $bottom) =
            (1, $board->board_size, 1, $board->board_size);
    }
    $self->drawGoban;
    for my $y ($top..$bottom) {
        for my $x ($left..$right) {
            my $coord = Waya::Coordinate->new(x => $x, y => $y);
            my $stone = $board->stone_at_coord($coord);
            next unless defined($stone);
            $self->placeStone($coord, $stone);
        }
    }
    $self->{image};   # convenience return value
}


sub render {
    my ($self, $board, $image_filename, $bounds) = @_;
    $self->render_image($board, $bounds);
    open my $fh, ">$image_filename" or
        die "can't open $image_filename for writing: $!\n";
    print $fh $self->{image}->gif;
    close $fh or die "can't close $image_filename: $!\n";
}


1;

